package com.whpost.api.controller.stamp.h5;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.whpost.service.config.Wdpz;
import com.whpost.service.dao.stamp.StampCardOrderMapper;
import com.whpost.service.dao.t.MyDao;
import com.whpost.service.dao.t.THyxxDao;
import com.whpost.service.dao.wx.TWxOrderDao;
import com.whpost.service.dao.wx.TWxUserDao;
import com.whpost.service.entity.wx.TWxOrder;
import com.whpost.service.service.stamp.StampOrderServices;
import com.whpost.service.service.stamp.h5.WxPay;
import com.whpost.service.tools.ReaderXmlForDOM;
import com.whpost.service.tools.ToolBean;
import com.whpost.service.tools.WxTools;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author: Yin Zhuoyi
 * @Date: 2023/3/29 9:35
 */
@Controller
@RequestMapping("/h5/pay")
public class PayController {

    @Resource
    private MyDao myDao;

    @Resource
    private TWxUserDao tWxUserDao;

    @Resource
    private WxPay wxPay;

    @Resource
    private TWxOrderDao tWxOrderDao;

    @Resource
    private StampCardOrderMapper stampCardOrderMapper;

    @Resource
    private StampOrderServices stampOrderServices;

    @Resource
    private Wdpz wdpz;

    @Resource
    private THyxxDao tHyxxDao;

    private final static String APP_ID="wxc363f1f58277ae1f";
    private final static String MCH_ID="1273405701";
    private final static String APP_KEY="apoilkjuhynb6754321asdghjyjuiklj";

    @RequestMapping(value = "paysuc")
    public @ResponseBody String paySuc(HttpServletRequest request){
        String rtnStr="";
        TWxOrder tWxOrder = new TWxOrder();
        try
        {
            ToolBean.info("支付通知结果接收到信息...");
            Vector<String> v_zd = new Vector<String>();
            StringBuffer sb = new StringBuffer();
            InputStream is = request.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "UTF-8");
            BufferedReader br = new BufferedReader(isr);
            String s = "";
            while ((s = br.readLine()) != null) {
                sb.append(s);
            }
            String receiveMsg = sb.toString(); //次即为接收到微信端发送过来的xml数据
            ToolBean.info("信息内容："+receiveMsg);

            SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
            parameters = ReaderXmlForDOM.parse(receiveMsg);
            ToolBean.info("解析出SortedMap："+parameters);

            String send_out_trade_no = ReaderXmlForDOM.parse(receiveMsg, "out_trade_no");
            if (send_out_trade_no == null) send_out_trade_no="";

            String transaction_id = ReaderXmlForDOM.parse(receiveMsg, "transaction_id");

            String sign=wxPay.createSign("UTF-8", parameters, APP_KEY);

            boolean checkSign =  ReaderXmlForDOM.parse(receiveMsg, "sign").equals(sign);

            ToolBean.info("签名验证结果："+checkSign);

            if (!checkSign)
            {
                ToolBean.info("签名验证失败，不返回任何信息！");
                return rtnStr;
            }
            else
            {
                if (StringUtils.isEmpty(send_out_trade_no))
                {
                    ToolBean.info("没有返回send_out_trade_no："+receiveMsg);
                    return rtnStr;
                }
                else
                {
                    ToolBean.info("获取到商户订单号："+send_out_trade_no);
                    tWxOrder = tWxOrderDao.selectOne(new QueryWrapper<TWxOrder>().eq("send_out_trade_no",send_out_trade_no));
                    String ywclState = tWxOrder.getYwclState();
                    if (org.apache.commons.lang3.StringUtils.isEmpty(ywclState)) ywclState = "0";
                    if (ywclState.equals("1"))
                    {
                        ToolBean.info("商户订单："+send_out_trade_no+"+业务已经处理了，直接返回信息！");
                        rtnStr ="<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                        return rtnStr;
                    }
                    else
                    {
                        //开始逻辑处理
                        ToolBean.info("商户订单号："+send_out_trade_no+"开始逻辑处理...");
                        String rtn = wxPay.paySucDone(send_out_trade_no,transaction_id);
                        JSONObject jsonObject = JSON.parseObject(rtn);
                        String code = jsonObject.getString("code");
                        ToolBean.info("商户订单号："+send_out_trade_no+"逻辑处理结果："+jsonObject);
                        ToolBean.info("商户订单号："+send_out_trade_no+"逻辑处理结果返回[CODE]："+code);
                        if (code.equals("200"))
                        {
                            rtnStr ="<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                            return rtnStr;
                        }
                    }
                }
            }

        }
        catch (Exception e)
        {
            ToolBean.info("通知发生错误！"+e.toString());
        }
        return "";
    }

    /**
     * 根据商户号查询支付状态
     * @param shh
     * @param request
     * @return
     */
    @RequestMapping(value = "query")
    public @ResponseBody String query(String shh,HttpServletRequest request){
        try
        {
            //准备数据
            String timestamp = myDao.getTimestamp();

            String appid=APP_ID;
            String mch_id=MCH_ID;
            String out_trade_no=shh;
            String nonce_str=ToolBean.getRandomString(30);
            SortedMap<Object,Object > parameters = new TreeMap<Object,Object>();
            parameters.put("appid", appid);
            parameters.put("mch_id", mch_id);
            parameters.put("nonce_str", nonce_str);
            parameters.put("out_trade_no", out_trade_no);
            String key= APP_KEY;
            String sign=wxPay.createSign("UTF-8", parameters, key);

            String sendorderxml = "";
            sendorderxml +="<xml>";
            sendorderxml +="<appid><![CDATA[%1$s]]></appid>";
            sendorderxml +="<mch_id><![CDATA[%2$s]]></mch_id>";
            sendorderxml +="<nonce_str><![CDATA[%3$s]]></nonce_str>";
            sendorderxml +="<sign><![CDATA[%4$s]]></sign>";
            sendorderxml +="<out_trade_no><![CDATA[%5$s]]></out_trade_no>";
            sendorderxml +="</xml>";
            String str = String.format(sendorderxml,appid, mch_id,  nonce_str, sign, out_trade_no);
            ToolBean.info("查询商户号["+out_trade_no+"]付款订单--发送的内容:"+str);

            ToolBean.info("开始查询商户号["+out_trade_no+"]付款订单...");
            WxTools wxTools = new WxTools();
            String a = wxTools.httpRequestxml("https://api.mch.weixin.qq.com/pay/orderquery", "POST", str);
            ToolBean.info("开始查询商户号["+out_trade_no+"]付款订单--返回结果 xml:"+a);
            String return_code = ReaderXmlForDOM.parse(a, "return_code");
            String return_code_url = ReaderXmlForDOM.parse(a, "code_url");
            if (return_code.equals("SUCCESS"))
            {
                String result_code = ReaderXmlForDOM.parse(a, "result_code");
                if (result_code.equals("SUCCESS")){
                    String trade_state = ReaderXmlForDOM.parse(a, "trade_state");
                    if (trade_state.equals("SUCCESS")){
                        //更新
                        TWxOrder tWxOrder = tWxOrderDao.getTWxOrderByTradeNo(out_trade_no);
                        return stampOrderServices.dealDdxxByWxOrder(tWxOrder);
                    }else{
                        String trade_state_desc = ReaderXmlForDOM.parse(a, "trade_state_desc");
                        return "{\"code\":\"0\",\"msg\":\""+trade_state_desc+"\"}";

                    }

                }else{
                    String err_code_des = ReaderXmlForDOM.parse(a, "err_code_des");
                    return "{\"code\":\"0\",\"msg\":\""+err_code_des+"\"}";
                }

            }
            else
            {
                //删除wx_order;
                ToolBean.info("开始查询商户号["+out_trade_no+"]付款订单失败");
                return "{\"code\":\"0\",\"msg\":\"查询失败\"}";
            }

        }
        catch (Exception e)
        {
            e.printStackTrace();
            ToolBean.info("/h5/pay/query发生错误！："+e.toString());
            return "{\"code\":\"0\",\"msg\":\"查询失败\"}";
        }
    }

    /**
     * 退款
     * @param shh
     * @param request
     * @return
     */
    @RequestMapping(value = "tk")
    @SaCheckPermission(value = {"wx:tk"}, mode = SaMode.OR)
    public @ResponseBody String tk(String shh,HttpServletRequest request){
        try
        {
            //准备数据
            String timestamp = myDao.getTimestamp();

            String appid=APP_ID;
            String mch_id=MCH_ID;
            String out_trade_no=shh;
            String nonce_str=ToolBean.getRandomString(30);
            SortedMap<Object,Object > parameters = new TreeMap<Object,Object>();
            parameters.put("appid", appid);
            parameters.put("mch_id", mch_id);
            parameters.put("nonce_str", nonce_str);
            parameters.put("out_trade_no", out_trade_no);
            String key= APP_KEY;
            String sign=wxPay.createSign("UTF-8", parameters, key);

            String sendorderxml = "";
            sendorderxml +="<xml>";
            sendorderxml +="<appid><![CDATA[%1$s]]></appid>";
            sendorderxml +="<mch_id><![CDATA[%2$s]]></mch_id>";
            sendorderxml +="<nonce_str><![CDATA[%3$s]]></nonce_str>";
            sendorderxml +="<sign><![CDATA[%4$s]]></sign>";
            sendorderxml +="<out_trade_no><![CDATA[%5$s]]></out_trade_no>";
            sendorderxml +="</xml>";
            String str = String.format(sendorderxml,appid, mch_id,  nonce_str, sign, out_trade_no);
            ToolBean.info("查询商户号["+out_trade_no+"]付款订单--发送的内容:"+str);

            ToolBean.info("开始查询商户号["+out_trade_no+"]付款订单...");
            WxTools wxTools = new WxTools();
            String a = wxTools.httpRequestxml("https://api.mch.weixin.qq.com/pay/orderquery", "POST", str);
            ToolBean.info("开始查询商户号["+out_trade_no+"]付款订单--返回结果 xml:"+a);
            String return_code = ReaderXmlForDOM.parse(a, "return_code");
            String return_code_url = ReaderXmlForDOM.parse(a, "code_url");
            if (return_code.equals("SUCCESS"))
            {
                String result_code = ReaderXmlForDOM.parse(a, "result_code");
                if (result_code.equals("SUCCESS")){
                    String trade_state = ReaderXmlForDOM.parse(a, "trade_state");
                    if (trade_state.equals("SUCCESS")){
                        //更新
                        TWxOrder tWxOrder = tWxOrderDao.getTWxOrderByTradeNo(out_trade_no);
                        return stampOrderServices.dealDdxxByWxOrder(tWxOrder);
                    }else{
                        String trade_state_desc = ReaderXmlForDOM.parse(a, "trade_state_desc");
                        return "{\"code\":\"0\",\"msg\":\""+trade_state_desc+"\"}";

                    }

                }else{
                    String err_code_des = ReaderXmlForDOM.parse(a, "err_code_des");
                    return "{\"code\":\"0\",\"msg\":\""+err_code_des+"\"}";
                }

            }
            else
            {
                //删除wx_order;
                ToolBean.info("开始查询商户号["+out_trade_no+"]付款订单失败");
                return "{\"code\":\"0\",\"msg\":\"查询失败\"}";
            }

        }
        catch (Exception e)
        {
            e.printStackTrace();
            ToolBean.info("/h5/pay/query发生错误！："+e.toString());
            return "{\"code\":\"0\",\"msg\":\"查询失败\"}";
        }
    }
}
